package com.corpgovernment.organization.service.budget;

import cn.hutool.core.collection.CollectionUtil;
import com.corpgovernment.api.car.product.dto.response.QueryOrderDetailResponseVo;
import com.corpgovernment.api.platform.soa.getpaypaymentbill.allData.response.GetAllPayBillDataResponse;
import com.corpgovernment.common.base.AbstractBaseService;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.enums.OrderTypeEnum;
import com.corpgovernment.organization.dataloader.CarOrderClientLoader;
import com.corpgovernment.organization.dataloader.PpPaymentBillClientLoader;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class BudgetCountService extends AbstractBaseService {

    @Autowired
    private PpPaymentBillClientLoader ppPaymentBillClientLoaderl;
    @Autowired
    private CarOrderClientLoader carOrderClientLoader;



    public JSONResult<Object> count() {
        try {
            initElkLog();
            /*1.所有支付单   所有退款单         根据订单ID  分组       计算每条订单消费金额
            2.然后根据订单-退款单  里的订单id  查询出每个产线里的人    根据支付单金额计算出每个人划分的金额
            3.然后根据产品中心/部门分组   计算出每个产品中心需要扣除的金额
            4.根据产品中心/部门查询出对应的预算进行扣款*/

            //查询支付单   获取所有公司支付订单   进行各个产线反推订单数据反推
            Map<String, List<GetAllPayBillDataResponse>> allPay = ppPaymentBillClientLoaderl.getAllPay(false);

            addElkInfoLog("获取到所有产线支付单数据: %s", JsonUtils.toJsonString(allPay));

            //叫车订单处理
            List<QueryOrderDetailResponseVo> car = carOrderDataManage(allPay.get(OrderTypeEnum.CN.getType()));

            //国内酒店处理
            List<QueryOrderDetailResponseVo> hotel = hotelOrderDataManage(allPay.get(OrderTypeEnum.HN.getType()));

            //国际酒店处理
            //hotelLintelOrderDataManage(allPay.get(OrderTypeEnum.HN.getType()));

        } finally {
            log.info("所有产线支付单金额预算处理:{}", getElkInfoLog());
            clearElkLog();
        }






        return null;
    }

    private List<QueryOrderDetailResponseVo> hotelOrderDataManage(List<GetAllPayBillDataResponse> getAllPayBillDataResponses) {
        if (CollectionUtil.isEmpty(getAllPayBillDataResponses)) {
            return Lists.newArrayList();
        }
        addElkInfoLog("开始处理酒店预算逻辑 %s", JsonUtils.toJsonString(getAllPayBillDataResponses));

        //查询出所有酒店订单   根据订单号查询出所有乘车人   根据乘车人平均分打车费(如有外部用户则扣预定人的费用)  添加预算占用表  -> 修改预算主表实际使用金额
        List<Long> orderList = getAllPayBillDataResponses.stream().map(GetAllPayBillDataResponse::getOrderId).collect(Collectors.toList());



        return null;
    }

    /**
     * 打车数据处理
     * @param payBillDataLists
     */
    private List<QueryOrderDetailResponseVo> carOrderDataManage(List<GetAllPayBillDataResponse> payBillDataLists) {
        if (CollectionUtil.isEmpty(payBillDataLists)) {
            return Lists.newArrayList();
        }
        addElkInfoLog("开始处理打车预算逻辑 %s", JsonUtils.toJsonString(payBillDataLists));

        //查询出所有打车订单   根据订单号查询出所有乘车人   根据乘车人平均分打车费(如有外部用户则扣预定人的费用)  添加预算占用表  -> 修改预算主表实际使用金额
        List<Long> orderList = payBillDataLists.stream().map(GetAllPayBillDataResponse::getOrderId).collect(Collectors.toList());

        Map<Long, List<QueryOrderDetailResponseVo>> carPassengerList = carOrderClientLoader.getCarPassengerByOrderId(orderList);

        addElkInfoLog("获取到打车的出行人 %s", JsonUtils.toJsonString(carPassengerList));

        //根据出行人处理支付单金额  平局划分到每个产品中心或者部门上
        return calculatedAmount(payBillDataLists, carPassengerList);
    }

    private List<QueryOrderDetailResponseVo> calculatedAmount(List<GetAllPayBillDataResponse> payBillDataLists, Map<Long, List<QueryOrderDetailResponseVo>> carPassengerList) {
        List<QueryOrderDetailResponseVo> passengerList = Lists.newArrayList();

        for (GetAllPayBillDataResponse payBillDataList : payBillDataLists) {
            List<QueryOrderDetailResponseVo> list = carPassengerList.get(payBillDataList.getOrderId());
            if (CollectionUtils.isEmpty(list)) {
                continue;
            }
            passengerList.addAll(calculationRules(list, payBillDataList));
        }
        return passengerList;
    }

    private List<QueryOrderDetailResponseVo> calculationRules(List<QueryOrderDetailResponseVo> list, GetAllPayBillDataResponse payBillDataList) {
        BigDecimal result = payBillDataList.getAmount().divide(new BigDecimal(list.size()));

        BigDecimal amount = payBillDataList.getAmount();
        for (int i = 0; i < list.size(); i++) {
            if (list.size() - 1 == i) {
                list.get(i).setAmount(amount);
            } else {
                amount = amount.subtract(result);
                list.get(i).setAmount(result);
            }
        }
        return list;
    }
}
